﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace WindowsGame1.Model
{
    class Level
    {     
        //fält
        //bredden och höjden på banan
        public const int g_levelWidth = 200;
        public const int g_levelHeight = 20;

        //håller reda på vilken nivå vi befinner oss på
        public int atLevel = 1;

        //listor som håller reda på positioner
        List<Vector2> enemiesPositions = new List<Vector2>();
        List<Vector2> minePositions = new List<Vector2>();

        //funktion som byter nivå
        public void NextLevel(int a_level)
        {
            atLevel = a_level;
            GenerateLevel();
        }

        //the 2D array of tiles
        internal Tile[,] _tiles = new Tile[g_levelWidth, g_levelHeight];

        //konstruktor som startar banan
        internal Level()
        {
            GenerateLevel();
        }

        //metod för att generera nivån
        private void GenerateLevel()
        {
            if (atLevel == 1)
            {
                Levels.Level1 lvl = new Levels.Level1();
                _tiles = lvl.GenerateLevel();
            }

            if (atLevel == 2)
            {
                Levels.Level2 lvl = new Levels.Level2();
                _tiles = lvl.GenerateLevel();
            }

            if (atLevel == 3)
            {
                Levels.Level3 lvl = new Levels.Level3();
                _tiles = lvl.GenerateLevel();
            }
        }
        
        //Hämtar kyckling-fiendernas position
        public List<Vector2> GetEnemyPositions()
        {
            enemiesPositions = new List<Vector2>();
            for (int x = 0; x < g_levelWidth; x++)
            {
                for (int y = 0; y < g_levelHeight; y++)
                {
                    if (_tiles[x, y]._tileType ==  Tile.TileType.T_CHICKEN_SPAWN_POSITION)
                    {
                        enemiesPositions.Add(new Vector2(x, y));
                    }
                }
            }
            return enemiesPositions;
        }

        //Hämtar minornas position
        internal List<Vector2> GetEnemyMinesPositions()
        {
            minePositions = new List<Vector2>();
            for (int x = 0; x < g_levelWidth; x++)
            {
                for (int y = 0; y < g_levelHeight; y++)
                {
                    if (_tiles[x, y]._tileType == Tile.TileType.T_MINE_SPAWN_POSITION)
                    {
                        minePositions.Add(new Vector2(x, y));
                    }
                }
            }
            return minePositions;
        }

        //Hämtar morötternas position
        public List<Vector2> GetCarrotPositions()
        {
            List<Vector2> carrotPositions = new List<Vector2>();
            for (int x = 0; x < g_levelWidth; x++)
            {
                for (int y = 0; y < g_levelHeight; y++)
                {
                    if (_tiles[x, y]._tileType == Tile.TileType.T_CARROT_POSITION)
                    {
                        carrotPositions.Add(new Vector2(x, y));
                    }
                }
            }
            return carrotPositions;
        }

        //Hämtar stalkerns position
        public List<Vector2> GetStalkersPosition()
        {
            List<Vector2> stalkerPosition = new List<Vector2>();
            for (int x = 0; x < g_levelWidth; x++)
            {
                for (int y = 0; y < g_levelHeight; y++)
                {
                    if (_tiles[x, y]._tileType == Tile.TileType.T_STALKING_CHICKEN_SPAWN)
                    {
                        stalkerPosition.Add(new Vector2(x, y));
                    }
                }
            }
            return stalkerPosition;
        }

        //funktion för att hämta nivån
        public int GetCurrentLevel()
        {
            return atLevel;
        }

        /**
         * Kollision för tiles
         */ 
        public bool IsCollidingAtGround(Vector2 a_pos, Vector2 a_size)
        {
            Vector2 topLeft = new Vector2(a_pos.X - a_size.X / 2.0f, a_pos.Y - a_size.Y);
            Vector2 bottomRight = new Vector2(a_pos.X + a_size.X / 2.0f, a_pos.Y);


            for (int x = 0; x < g_levelWidth; x++)
            {
                for (int y = 0; y < g_levelHeight; y++)
                {

                    if (bottomRight.X < (float)x)
                        continue;
                    if (bottomRight.Y < (float)y)
                        continue;
                    if (topLeft.X > (float)x + 1.0f)
                        continue;
                    if (topLeft.Y > (float)y + 1.0f)
                        continue;

                    if (_tiles[x, y]._tileType == Tile.TileType.T_BLOCKED || _tiles[x, y]._tileType == Tile.TileType.T_GROUND)
                    {
                        return true;
                    }
                }
            }


            return false;
        }

        public bool IsCollidingAtNothing(Vector2 a_pos, Vector2 a_size)
        {
            Vector2 topLeft = new Vector2(a_pos.X - a_size.X / 2.0f, a_pos.Y - a_size.Y);
            Vector2 bottomRight = new Vector2(a_pos.X + a_size.X / 2.0f, a_pos.Y);


            for (int x = 0; x < g_levelWidth; x++)
            {
                for (int y = 0; y < g_levelHeight; y++)
                {

                    if (bottomRight.X < (float)x)
                        continue;
                    if (bottomRight.Y < (float)y)
                        continue;
                    if (topLeft.X > (float)x + 1.0f)
                        continue;
                    if (topLeft.Y > (float)y + 1.0f)
                        continue;

                    if (_tiles[x, y]._tileType == Tile.TileType.T_EMPTY)
                    {
                        return true;
                    }
                }
            }


            return false;
        }

        public bool IsCollidingAtTrap(Vector2 a_pos, Vector2 a_size)
        {
            Vector2 topLeft = new Vector2(a_pos.X - a_size.X / 2.0f, a_pos.Y - a_size.Y);
            Vector2 bottomRight = new Vector2(a_pos.X + a_size.X / 2.0f, a_pos.Y);


            for (int x = 0; x < g_levelWidth; x++)
            {
                for (int y = 0; y < g_levelHeight; y++)
                {

                    if (bottomRight.X < (float)x)
                        continue;
                    if (bottomRight.Y < (float)y)
                        continue;
                    if (topLeft.X > (float)x + 1.0f)
                        continue;
                    if (topLeft.Y > (float)y + 1.0f)
                        continue;

                    if (_tiles[x, y]._tileType == Tile.TileType.T_TRAP)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        public bool IsCollidingAtBasket(Vector2 a_pos, Vector2 a_size)
        {
            Vector2 topLeft = new Vector2(a_pos.X - a_size.X / 2.0f, a_pos.Y - a_size.Y);
            Vector2 bottomRight = new Vector2(a_pos.X + a_size.X / 2.0f, a_pos.Y);


            for (int x = 0; x < g_levelWidth; x++)
            {
                for (int y = 0; y < g_levelHeight; y++)
                {

                    if (bottomRight.X < (float)x)
                        continue;
                    if (bottomRight.Y < (float)y)
                        continue;
                    if (topLeft.X > (float)x + 1.0f)
                        continue;
                    if (topLeft.Y > (float)y + 1.0f)
                        continue;

                    if (_tiles[x, y]._tileType == Tile.TileType.T_BASKET)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

    }
}
